<template>
  <view class="tn-calendar">

    <!-- 顶部年份操作 -->
    <view v-if="allowSwitchYear" class="tn-calendar__operation">
      <view class="operation__year">
        <view
          class="prev"
          :class="{'disabled': minYear && year <= minYear}"
          @tap.stop="handleYearSwitch('prev')"
        >
          <tn-icon icon="left"></tn-icon>
        </view>
        <view class="value">{{ year }}</view>
        <view
          class="next"
          :class="{'disabled': maxYear && year >= maxYear}"
          @tap.stop="handleYearSwitch('next')"
        >
          <tn-icon icon="right"></tn-icon>
        </view>
      </view>
    </view>
    
    <!-- 顶部中文数据 -->
    <view class="tn-calendar__header">
      <view
        v-for="(item, index) in weekdayZh"
        :key="index"
        class="title"
      >{{ item }}</view>
    </view>

    <!-- 内容区域, 完整的日历 -->
    <view class="tn-calendar__content" :style="contentStyle">
      <swiper
        class="content__swiper"
        :indicator-dots="false"
        :autoplay="false"
        :circular="false"
        :duration="250"
        :vertical="false"
        :current="currentShowMonth"
        @change="handleSwiperChange"
      >
        <swiper-item
          v-for="(item, index) in calendarData"
          :key="index"
          class="content__swiper-item"
        >
          <!-- 背景 -->
          <view class="content__bg">
            <view class="content__month-value">
              {{ item.month }}
            </view>
          </view>
          <!-- 日期数据 -->
          <view class="content__data">
            <view
              v-for="(dateItem, dateIndex) in item.data"
              :key="dateIndex"
              class="value"
              :class="dateValueClass(index, dateIndex)"
              :style="dateValueStyle(index, dateIndex)"
              @tap.stop="handleDateClick(dateItem.value)"
            >
              {{ dateItem.value }}
              <view v-if="dateItem.desc" class="desc">
                {{ dateItem.desc }}
              </view>
            </view>
          </view>
          
        </swiper-item>
      </swiper>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { computed, CSSProperties, watch } from 'vue'
import TnIcon from '../../tn-icon/src/Icon.vue'
import { calendarProps, calendarEmits, CalendarMode } from '../../../types/tn-calendar'
import { ColorInfo } from '../../../types/tuniao-ui'
import useComponentColor from '../../../libs/hooks/useComponentColor'
import useDateInfo from '../lib/useDateInfo'
import { subNumber } from '../../../utils'

const props = defineProps(calendarProps)
const emits = defineEmits(calendarEmits)

const {
  weekdayZh,
  year,
  month,
  day,
  startYear,
  startMonth,
  startDay,
  startDate,
  endYear,
  endMonth,
  endDay,
  endDate,
  minYear,
  maxYear,
  currentShowMonth,
  calendarData,
  selectValue,
  init,
  setDefaultValue,
  updateCurrentShowMonth,
  updateSelectYear,
  updateSelectValue
} = useDateInfo()

const { splitColorInfo } = useComponentColor()

// 解析字体颜色
const fontColor = computed<ColorInfo>(() => {
  return splitColorInfo('color', props?.color || '')
})
// 解析激活时字体颜色
const activeFontColor = computed<ColorInfo>(() => {
  return splitColorInfo('color', props?.activeColor || '')
})
// 解析日期范围内字体颜色
const rangeFontColor = computed<ColorInfo>(() => {
  return splitColorInfo('color', props?.rangeColor || '')
})
// 解析激活时背景颜色
const activeBgColor = computed<ColorInfo>(() => {
  return splitColorInfo('bg', props?.activeBgColor || '')
})
// 解析日期范围内背景颜色
const rangeBgColor = computed<ColorInfo>(() => {
  return splitColorInfo('bg', props?.rangeBgColor || '')
})

// 内容区域样式
const contentStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}

  // 计算容器的高度, 根据显示数据的长度确定
  const dataLength = calendarData.value[currentShowMonth.value]?.data.length || 0
  style.height = Math.ceil(dataLength / 7) * 100 + 'rpx'

  return style
})
// 日期的样式
const dateValueStyle = computed<(monthIndex: number, index: number) => CSSProperties>(() => {
  return (monthIndex: number, index: number) => {
    let style: CSSProperties = {}

    // 获取对应日期的数据
    const date = calendarData.value[monthIndex]?.data[index]
    const currenMonth = calendarData.value[monthIndex]?.month || 0
    if(date?.select) {
      if (props?.mode === 'range') {
        
        if (startMonth.value === currenMonth && date?.value === startDay.value) {
          if (activeFontColor.value.type === 'style') {
          style.color = activeFontColor.value.value
          }
          if (activeBgColor.value.type === 'style') {
            style.backgroundColor = activeBgColor.value.value
          }
        } else if (endMonth.value === currenMonth && date?.value === endDay.value) {
          if (activeFontColor.value.type === 'style') {
          style.color = activeFontColor.value.value
          }
          if (activeBgColor.value.type === 'style') {
            style.backgroundColor = activeBgColor.value.value
          }
        } else {
          if (rangeFontColor.value.type === 'style') {
            style.color = rangeFontColor.value.value
          }
          if (rangeBgColor.value.type === 'style') {
            style.backgroundColor = rangeBgColor.value.value
          }
        }
      } else {
        if (activeFontColor.value.type === 'style') {
          style.color = activeFontColor.value.value
        }
        if (activeBgColor.value.type === 'style') {
          style.backgroundColor = activeBgColor.value.value
        }
      }
    } else {
      if (fontColor.value.type === 'style') {
        style.color = fontColor.value.value
      }
    }


    return style
  }
})

// 日期对应的类
const dateValueClass = computed<(monthIndex: number, index: number) => string>(() => {
  return (monthIndex: number, index: number) => {
    let clazz: string[] = []

    // 获取对应日期的数据
    const date = calendarData.value[monthIndex]?.data[index]
    const currenMonth = calendarData.value[monthIndex]?.month || 0
    if (date?.disabled) {
      clazz.push('disabled')
    }
    if(date?.select) {
      clazz.push('select')
      if (props?.mode === 'range') {
        
        if (startMonth.value === currenMonth && date?.value === startDay.value) {
          clazz.push('range-start')
          if (activeFontColor.value.type === 'class') {
            clazz.push(activeFontColor.value.value)
          }
          if (activeBgColor.value.type === 'class') {
            clazz.push(activeBgColor.value.value)
          }
        } else if (endMonth.value === currenMonth && date?.value === endDay.value) {
          clazz.push('range-end')
          if (activeFontColor.value.type === 'class') {
            clazz.push(activeFontColor.value.value)
          }
          if (activeBgColor.value.type === 'class') {
            clazz.push(activeBgColor.value.value)
          }
        } else {
          clazz.push('range')
          if (rangeFontColor.value.type === 'class') {
            clazz.push(rangeFontColor.value.value)
          }
          if (rangeBgColor.value.type === 'class') {
            clazz.push(rangeBgColor.value.value)
          }
        }
      } else {
        if (activeFontColor.value.type === 'class') {
          clazz.push(activeFontColor.value.value)
        }
        if (activeBgColor.value.type === 'class') {
          clazz.push(activeBgColor.value.value)
        }
      }
    } else {
      if (fontColor.value.type === 'class') {
        clazz.push(fontColor.value.value)
      }
    }

    return clazz.join(' ')
  }
})

// 标记是否为内部修改
let interUpdate: boolean = false

watch(() => props.modelValue, (val) => {
  if (interUpdate) {
    interUpdate = !interUpdate
    return
  }
  // console.log('modelValue', val);
  setDefaultValue(val as (string | string[]))
})

// 初始化日历数据
let initFlag: boolean = false
const initCalendar = () => {
  init(
    props.modelValue as (string | string[]),
    props.mode as CalendarMode,
    props.minDate,
    props.maxDate,
    props.showLunar,
    props.startText,
    props.endText
  )
  // console.log(calendarData.value)
  initFlag = true
}
initCalendar()

watch(selectValue, (val) => {
  if (initFlag) {
    interUpdate = true
    // console.log('selectValue', val);
    emits('update:modelValue', val)

    if (props.mode === 'date' || props.mode === 'multi') {
      emits('change', {
        year: year.value,
        month: month.value,
        day: day.value,
        date: `${year.value}/${subNumber(month.value)}/${subNumber(day.value)}`
      })
    } else if (props.mode === 'range') {
      emits('change', {
        year: year.value,
        month: month.value,
        day: day.value,
        date: `${year.value}/${subNumber(month.value)}/${subNumber(day.value)}`,
        startYear: startYear.value,
        startMonth: startMonth.value,
        startDay: startDay.value,
        startDate: startDate.value,
        endYear: endYear.value,
        endMonth: endMonth.value,
        endDay: endDay.value,
        endDate: endDate.value
      })
    }
  }
}, {
  deep: true
})

// 切换年份
const handleYearSwitch = (type: 'prev' | 'next') => {
  if (!props.allowSwitchYear) return
  updateSelectYear(type === 'prev' ? year.value - 1 : year.value + 1)
  emits('change-year', year.value)
}

// 处理月份切换
const handleSwiperChange = (e: any) => {
  // console.log(e.detail.current);
  if (!props.allowSwitchMonth) return
  updateCurrentShowMonth(e.detail.current)
  emits('change-month', month.value)
}

// 处理日期点击
const handleDateClick = (val: string | number) => {
  updateSelectValue(val)
}
</script>

<style lang="scss" scoped>
@import '../../../theme.scss';
.tn-calendar {
  position: relative;
  width: 100%;
  overflow: hidden;

  &__operation {
    width: 100%;

    .operation__year {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      line-height: 1;
      margin-bottom: 10rpx;
      .prev {
        padding-right: 20rpx;
      }
      .next {
        padding-left: 20rpx;
      }
      .prev,.next {
        font-size: 26rpx;
        margin-top: 2rpx;
        &.disabled {
          color: #FEFEFE;
        }
      }
      .value {
        font-size: 36rpx;
      }
    }
  }

  &__header {
    position: relative;
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    box-shadow: 0rpx 8rpx 8rpx 0rpx rgba(0, 0, 0, 0.01);
    z-index: 1;
    padding: 6rpx 0rpx;

    .title {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }

  &__content {
    position: relative;
    width: 100%;
    background-color: #FAFAFA;
    transition: height 0.25s ease;

    .content__swiper {
      height: 100%;
    }
    .content__bg {
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .content__month-value {
      font-size: 180rpx;
      font-weight: 600;
      opacity: 0.1;
    }

    .content__data {
      position: relative;
      width: 100%;
      display: flex;
      flex-wrap: wrap;

      .value {
        width: calc(100% / 7 - 10rpx);
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 90rpx;
        margin: 0rpx 5rpx;
        margin-top: 10rpx;

        &.disabled {
          color: #AAAAAA !important;
        }

        &.select {
          background-color: $tn-main-color;
          color: #FFFFFF;
          border-radius: 10rpx;
          .desc {
            color: inherit;
          }
          &.range {
            background-color: #E6E6E6;
            border-radius: 0rpx;
            color: $tn-main-color
          }
          &.range-start {
            border-radius: 10rpx 0rpx 0rpx 10rpx;
          }
          &.range-end {
            border-radius: 0rpx 10rpx 10rpx 0rpx;
          }
        }

        .desc {
          font-size: 18rpx;
          color: #AAAAAA;
        }
      }
    }
  }
}
</style>
